package com.cysyz.web.modules.base.upload.service;

import com.cysyz.mylib.io.filesavetool.IFileSaveTool;
import com.cysyz.mylib.io.filesavetool.impl.FileSavePathAndLogicPath;
import com.cysyz.mylib.io.filesavetool.impl.FileSaveToolImpl;
import com.cysyz.mylib.utils.PropertiesUtil;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by cuiyong on 15/5/28.
 */
public class UploadFileService {

    private String saveDir;

    private IFileSaveTool fileSaveTool;

    public UploadFileService() {
        this.saveDir = PropertiesUtil.getProperties(
                    UploadFileService.class.getResource("/config.properties").getFile()
                    ).getProperty("file.upload.docBase");
        if (saveDir == null) {
            throw new RuntimeException("there must be a config.properties in classpath, and has a property which key is file.upload.path.absolute");
        }
        fileSaveTool = new FileSaveToolImpl(
                saveDir,
                PropertiesUtil.getProperties(
                    UploadFileService.class.getResource("/config.properties").getFile()
                ).getProperty("file.upload.path")
        );
    }

    public String getRealSavePath(String logicPath, String fileSaveDir) {
        return fileSaveTool.getRealSavePath(logicPath, fileSaveDir);
    }

    public List<FileNameAndSaveFileInfo> uploadFiles(HttpServletRequest request, String dir) {
        return uploadFiles0(request, dir);
    }

    public List<FileNameAndSaveFileInfo> uploadFiles(HttpServletRequest request) {
        return this.uploadFiles0(request, "");
    }

    private List<FileNameAndSaveFileInfo> uploadFiles0(HttpServletRequest request, String dir) {
        StringBuilder saveDirBuilder = new StringBuilder("/");
        saveDirBuilder.append(saveDir);
        saveDirBuilder.append("/");
        saveDirBuilder.append(dir);
        List<FileNameAndSaveFileInfo> fileNameAndSavePaths = new ArrayList<>();

        //解析器解析request的上下文
        CommonsMultipartResolver multipartResolver =
                new CommonsMultipartResolver(request.getSession().getServletContext());
        //先判断request中是否包涵multipart类型的数据，
        if(multipartResolver.isMultipart(request)){
            //再将request中的数据转化成multipart类型的数据
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator iter = multiRequest.getFileNames();
            while(iter.hasNext()){
                MultipartFile file = multiRequest.getFile((String)iter.next());
                if(file != null){

                    String originalFilename = file.getOriginalFilename();
                    try {
                        fileNameAndSavePaths.add(
                            new FileNameAndSaveFileInfo(originalFilename,
                                fileSaveTool.saveFile(
                                        file.getBytes(),
                                        originalFilename,dir)
                                )
                        );
                    } catch (IOException e) {
                        throw new RuntimeException("upload file fail", e);
                    }
                }
            }
        }

        return fileNameAndSavePaths;
    }


    public static class FileNameAndSaveFileInfo {
        private String fileName;
        private FileSavePathAndLogicPath saveFileInfo;


        public FileNameAndSaveFileInfo(String fileName, FileSavePathAndLogicPath saveFileInfo) {
            this.fileName = fileName;
            this.saveFileInfo = saveFileInfo;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public FileSavePathAndLogicPath getSaveFileInfo() {
            return saveFileInfo;
        }

        public void setSaveFileInfo(FileSavePathAndLogicPath saveFileInfo) {
            this.saveFileInfo = saveFileInfo;
        }
    }
}